<?php
namespace app\model;

/**
 * Author: cbw
 * Desc: 自动发货上传购物信息接口
 * Time: 2023/3/4 16:51
 * Email: 17854288794@163.com
 */
class AutoShipment{

    /**
     * Desc:自动发货
     * User:cbw
     * Email:17854288794@163.com
     * Time: 2023/3/4 20:55
     * @param $system
     * @param $transaction_id
     * @param $good_desc
     * @param $openid
     * @return bool|string
     */
    public static function sureShipment($system,$transaction_id,$good_desc,$openid)
    {
        $access_token = getAccessToken($system);
        $order_key = [
            'order_number_type'=>2,//1商户单号  2微信支付单号
            'transaction_id'=>$transaction_id,//微信支付单号
        ];
        $logistics_type = 4;//实体物流配送采用快递公司进行实体物流配送形式 2、同城配送 3、虚拟商品，虚拟商品，例如话费充值，点卡等，无实体配送形式 4、用户自提
        $delivery_mode = 1;//发货模式枚举值：1、UNIFIED_DELIVERY（统一发货）2、SPLIT_DELIVERY（分拆发货）
        $shipping_list = [
            [
                'item_desc'=>$good_desc
            ]
        ];
        $upload_time = date("c",time());
        $payer = [
            'openid'=>$openid//用户openid
        ];
        $url = 'https://api.weixin.qq.com/wxa/sec/order/upload_shipping_info?access_token='.$access_token;
        $data = [
            'order_key'=>$order_key,
            'logistics_type'=>$logistics_type,
            'delivery_mode'=>$delivery_mode,
            'shipping_list'=>$shipping_list,
            'upload_time'=>$upload_time,
            'payer'=>$payer
        ];
        $res = self::curl($url,json_encode($data),array('Content-Type: application/json'));
        return $res;
    }

    /**
     * Desc:查询发货状态
     * User:cbw
     * Email:17854288794@163.com
     * Time: 2023/3/4 21:06
     * @param $system
     * @param $transaction_id
     * @return bool|string
     */
    public static function getOrder($system,$transaction_id)
    {
        $access_token = getAccessToken($system);
        $url = 'https://api.weixin.qq.com/wxa/sec/order/get_order?access_token='.$access_token;
        $data = [
            'transaction_id'=>$transaction_id
        ];
        $res = self::curl($url,json_encode($data),array('Content-Type: application/json'));
        return $res;
    }

    /**
     * Desc:请求类
     * User:cbw
     * Email:17854288794@163.com
     * Time: 2023/3/5 13:04
     * @param $url
     * @param false $post
     * @param array $header
     * @return bool|string
     */
    public static function curl($url, $post = false,$header = [])
    {
        $headerArray = array_merge($header, [
            'Expect:',
        ]);
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_HEADER, 0);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        if ($post) {
            curl_setopt($ch, CURLOPT_HTTPHEADER, $headerArray);
            curl_setopt($ch, CURLOPT_POST, 1);
            curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
        }
        $result = curl_exec($ch);
        curl_close($ch);
        return $result ? json_decode($result, true) : [];
    }

    /**
     * Desc:增加record表字段 记录订单发货状态
     * User:cbw
     * Email:17854288794@163.com
     * Time: 2023/3/5 13:34
     */
    public static function updateRecordFiled()
    {
        if (!db_fieldexists(MODULE_NAME.'_aorder','order_shipment_state')){
            $sql = "ALTER TABLE `yx_".MODULE_NAME."_aorder` ADD COLUMN `order_shipment_state` tinyint(1)  not null default 1 comment '订单发货状态 1未发货 2已发货 3确认收货 4交易完成 5已退款';";
            db_query($sql);
        }
    }

    /**
     * Desc:格式化异常错误信息
     * Author:cbw
     * Time: 2023/12/15 13:04
     * @param $key
     * @param $msg
     * @return string
     */
    public static function getErrorInfo($key,$msg='')
    {
        $tmp_att = [
            '-1'=>'系统繁忙，此时请开发者稍候再试',
            '10060001'=>'支付单不存在',
            '10060002'=>'支付单已完成发货，无法继续发货',
            '10060003'=>'支付单已使用重新发货机会',
            '10060004'=>'支付单处于不可发货的状态',
            '10060005'=>'物流类型有误',
            '10060006'=>'非快递发货时不允许分拆发货',
            '10060007'=>'分拆发货模式下必须填写 is_all_delivered 字段',
            '10060008'=>'商品描述 item_desc 字段不能为空',
            '10060009'=>'商品描述 item_desc 字段太长',
            '10060012'=>'系统繁忙，此时请开发者稍候再试',
            '10060014'=>'参数错误',
            '10060019'=>'系统繁忙，此时请开发者稍候再试',
            '10060020'=>'该笔支付单在没有任何商品描述的情况下不允许完成发货',
            '10060023'=>'发货信息未更新',
            '10060024'=>'物流信息列表太长',
            '10060025'=>'物流公司编码太长',
            '10060026'=>'物流单号太长',
            '10060031'=>'该笔支付单不属于 openid 所指定的用户',
            '268485216'=>'上传时间非法，请按照 RFC 3339 格式填写',
            '268485224'=>'发货模式非法',
            '268485195'=>'微信支付单号形式下 transaction_id 字段不能为空	',
            '268485196'=>'商户侧单号形式下 mchid 字段不能为空',
            '268485197'=>'商户侧单号形式下 out_trade_no 字段不能为空',
            '268485194'=>'订单单号类型非法',
            '268485228'=>'统一发货模式下，物流信息列表长度必须为 1',
            '268485226'=>'物流单号不能为空',
            '268485227'=>'物流公司编码不能为空',
        ];
        if (array_key_exists($key,$tmp_att)){
            return '未知错误,errorcode:'.$key.';errmsg:'.$msg.$tmp_att[$key];
        }
        return '未知错误,errorcode:'.$key.';errmsg:'.$msg;
    }

    /**
     * Desc:查询所有已支付待发货订单 处理自动发货
     * Author:cbw
     * Time: 2023/12/15 13:05
     * @param $system
     * @param $theme
     * @param $limit [每次执行多少个]
     */
    public static function getPayOrdersAutoShipment($system,$theme,$limit=20)
    {
        $success_total = 0;
        $error_total = 0;
        //判断17服务器 5服务器
        if ((DOMAIN0 == "17.yixuan.net" || DOMAIN0 == "18.yixuan.net" || DOMAIN0 == "5.yixuan.net") && $system['wxapp_shipment']>0){
            $is_trade_manager = self::getIsTradeManager($system);
            if (!$is_trade_manager){
                return ['success_total'=>$success_total,'error_total'=>$error_total,'msg'=>'暂不支持发货功能','remain_page'=>0,'total_page'=>0];
            }
            self::updateRecordFiled();
            //todo  查询已支付订单
            $goods_desc = $theme['title'];
            $sql = "  from ".tablename(t_order)." where themeid='".$theme['id']."' and paystate=1 and detailid>0 and realfee>0 and orderfee>0 and order_shipment_state=1";
            $remain_num = db_find("select count(*) as cnt".$sql)['cnt'];
            $order_list = db_select("select id,transaction_id,openid,order_shipment_state,detailid ".$sql." limit $limit");
            $remain_page = $total_page = 0;
            if ($order_list){
                foreach ($order_list as $k => $val){
                    //存在微信支付单号  存在openid
                    if ($val['transaction_id'] && $val['openid']){
                        $transaction_id = $val['transaction_id'];
                        //查询微信支付订单发货状态
                        $get_order = self::getOrder($system,$transaction_id);
                        if ($get_order){
                            if ($get_order['errcode']==48001){
                                //不存在接口 修改config中参数
                                yxlog('失败:当前订单或小程序不支持自动发货','小程序自动发货');
                            }elseif ($get_order['errcode']==0){
                                if ($val['order_shipment_state']==1){
                                    //存在接口
                                    $autoship = self::sureShipment($system,$transaction_id,$goods_desc,$val['openid']);
                                    if ($autoship['errcode']==0){
                                        //更新arecord 中订单发货状态
                                        $update = ['order_shipment_state'=>2];
                                        $where = ['themeid'=>$theme['id'],'id'=>$val['id']];
                                        db_update(t_order,$update,$where);
                                        $success_total+=1;
                                        yxlog('成功:定单号:'.($val['detailid']+9000).';自动发货成功','小程序自动发货');
                                    }else{
                                        $tmp_msg = self::getErrorInfo($autoship['errcode'],$autoship['errmsg']);
                                        $error_total+=1;
                                        yxlog('失败:定单号:'.($val['detailid']+9000).';'.$tmp_msg,'小程序自动发货');
                                    }
                                }else{
                                    if ($val['order_shipment_state']!=2){
                                        yxlog('异常:定单号:'.($val['detailid']+9000).';状态无法自动发货','小程序自动发货');
                                    }
                                }
                            }
                        }
                    }
                }
                if ($remain_num>0){
                    $total_page = $remain_num>0?ceil($remain_num/$limit):0;
                    $remain_page = $total_page-1;
                }
                return ['success_total'=>$success_total,'error_total'=>$error_total,'msg'=>'本次操作完成','remain_page'=>$remain_page,'total_page'=>$total_page];
            }else{
                return ['success_total'=>$success_total,'error_total'=>$error_total,'msg'=>'暂无待发货订单','remain_page'=>$remain_page,'total_page'=>$total_page];
            }
        }
    }

    /**
     * Desc:进入首页后查询3分钟前的支付待发货订单 进行发货处理
     * Author:cbw
     * Time: 2023/12/21 15:34
     * @param $system
     * @param $theme
     */
    public static function openIndexAfterShipment($system,$theme)
    {
        if ((DOMAIN0 == "17.yixuan.net" || DOMAIN0 == "18.yixuan.net" || DOMAIN0 == "5.yixuan.net") && $system['wxapp_shipment']>0){
            self::updateRecordFiled();
            $goods_desc = $theme['title'];
            $search_time = time()-180;
            $sql = " select id,transaction_id,openid,order_shipment_state,detailid from ".
                tablename(t_order)." where themeid='".$theme['id']."' and paystate=1 and detailid>0 and realfee>0 and orderfee>0 and order_shipment_state=1 and addtime<'".$search_time."' limit 1";
            $item = db_find($sql);
            if ($item && $item['transaction_id'] && $item['openid']){
                $transaction_id = $item['transaction_id'];
                //查询微信支付订单发货状态
                $get_order = self::getOrder($system,$transaction_id);
                if ($get_order){
                    if ($get_order['errcode']==48001){
                        yxlog('失败:当前订单或小程序不支持自动发货','小程序自动发货');
                    }elseif ($get_order['errcode']==0){
                        if ($item['order_shipment_state']==1){
                            //存在接口
                            $autoship = self::sureShipment($system,$transaction_id,$goods_desc,$item['openid']);
                            if ($autoship['errcode']==0){
                                //更新arecord 中订单发货状态
                                $update = ['order_shipment_state'=>2];
                                $where = ['themeid'=>$theme['id'],'id'=>$item['id']];
                                db_update(t_order,$update,$where);
                                yxlog('成功:定单号:'.($item['detailid']+9000).';自动发货成功','小程序自动发货');
                            }else{
                                $tmp_msg = self::getErrorInfo($autoship['errcode'],$autoship['errmsg']);
                                yxlog('失败:定单号:'.($item['detailid']+9000).';'.$tmp_msg,'小程序自动发货');
                            }
                        }else{
                            if ($item['order_shipment_state']!=2){
                                yxlog('异常:定单号:'.($item['detailid']+9000).';状态无法自动发货','小程序自动发货');
                            }
                        }
                    }
                }
            }
        }
    }

    /**
     * Desc:检测小程序是否开通发货信息管理服务
     * Author:cbw
     * Time: 2023/12/15 16:20
     * @param $system
     * @return array|bool|string
     */
    public static function getIsTradeManager($system)
    {
        $access_token = getAccessToken($system);
        $url = 'https://api.weixin.qq.com/wxa/sec/order/is_trade_managed?access_token='.$access_token;
        $data = [
            'appid'=>$system['appidxcx']
        ];
        $is_trade_manager = self::curl($url,json_encode($data),array('Content-Type: application/json'));
        if ($is_trade_manager && $is_trade_manager['errcode']==0 && $is_trade_manager['is_trade_managed']){
            return true;
        }else{
            return false;
        }
    }
}